Profile picture

[Docker-Compose] Include

JaehyoJJAng2024년 02월 20일

▶ include

  • include는 Docker Compose V2.20.3 이상 및 도커 데스크탑 V4.22 버전 이상에서 사용할 수 있다.

include를 사용하는 경우 별도의 Compose 파일을 로컬 Compose 파일에 직접 포함시킬 수 있다.

이를 통해 복잡한 애플리케이션을 하위 Compose 파일로 쉽게 모듈화가 가능하다.


▸ 예제

docker-compose.yaml

include:
  - my-compose-include.yaml  #with serviceB declared
services:
  serviceA:
    build: .
    depends_on:
      - serviceB #use serviceB directly as if it was declared in this Compose file

include에 정의된 my-compose-include.yaml은 데이터를 검사하는 웹 UI, 격리된 네트워크, 데이터 지속성을 위한 볼륨 등으로 관리될 수 있다.

이에 의존하는 애플리케이션은 세세한 인프라 정보를 알 필요가 없어지게 된다.


또 다른 예시를 살펴보자.
~/myProject/docker-compose.yaml

version: "3.9"

include:
  - "app.compose.yaml"
  - "nginx.compose.yaml"

networks:
  mynet:
    driver: bridge
    external: false

#
# defines named volumes used by nginx
#
volumes:
  nginx_data_container: {}

~/myProject/config/compose/app.compose.yaml

########################################
# APP :: Hosted by JaehyoJJAng
########################################
services:
  app:
    build: ../../server
    container_name: app-game-server
    stop_grace_period: ${PALWORLD_GRACEPERIOD}
    restart: ${PALWORLD_RESTARTTYPE}
    image: palhub-game-server
    volumes:
      - ../../logs:/app/logs # mount directory for storing logs
      - ../../logs/steam:/home/steam/.steam/steam/logs # add steam logs
      - ../../backups:/app/backups
      - ../../server/palworld:/app/PalServer/Pal
      - /etc/machine-id:/etc/machine-id:ro
      - /etc/localtime:/etc/localtime:ro
    env_file:
      - ../../.env
    networks:
      - mynet

~/myProject/config/compose/app.compose.yaml

########################################
# NGINX :: Hosted by JaehyoJJAng
########################################
services:
  nginx:
    image: nginx:mainline-alpine
    container_name: palhub-nginx
    restart: unless-stopped
    ports:
      - 80:80   # website: basic http site
      # - 443:443 # website: ssl enabled site # ! uncomment when/if ssl support added
      # palworld: main server communication line
      - ${PALWORLD_GAME_PORT}:8211/udp
      # palworld: allows server to show up in the community servers tab
      - ${PALWORLD_COMM_PORT}:27015/udp
      # palworld: allows rcon to communicate with server
      - ${PALWORLD_RCON_PORT}:25575
    volumes:
      - nginx_data_container:/var/www/html
      - ../../server/palworld:/app/palworld
      - ../../config/nginx:/etc/nginx
      - ../../logs/nginx:/var/log/nginx
      - ../../logs:/app/logs
    depends_on:
      - app
    env_file:
      - ../../.env
    networks:
      - mynet

docker-compose.yaml에서 정의한 volumes, networks을 하위 Compose 파일에서도 사용할 수 있는 것을 볼 수 있고,

nginx 컨테이너에서 정의된 depends_on을 보면 app 컨테이너를 지정하고 있는 것을 확인할 수 있는데

include에 정의된 하위 Compose 간 각 컨테이너들을 호출하여 사용할 수 있다는 뜻이 된다.


‣ 응용 (1)

  • leafy-front: Vue.js 3 기반 프론트 앤드 소스
  • leafy: Spring Boot 백엔드 애플리케이션, Spring Boot Tomcat WAS 서버
  • leafy-postgres: 데이터베이스 서버

image
위 세 개의 컨테이너를 include 옵션을 사용하여 별도로 관리해보도록 하자.


먼저 프로젝트 구조는 아래와 같다.

tree -L 1 . 
.
├── composes
├── docker-compose.yml
├── leafy-backend
├── leafy-frontend
├── leafy-postgresql
└── scripts

5 directories, 1 file

docker-compose.yaml은 아래와 같이 작성해주자.
~/leafy/docker-compose.yaml

version: "3.9"

include:
  - "composes/postgresql.yaml"
  - "composes/backend.yaml"
  - "composes/frontend.yaml"

networks:
  leafy-network:
    driver: bridge
    external: true

volumes:
  mydata: {}

각 애플리케이션에 대한 compose.yaml은 다음과 같다.


1. postgresql
composes/postgresql.yaml

services:
  leafy-postgres:
    build: ../leafy-postgresql
    image: leafy-postgres:5.0.0-compose
    volumes:
      - type: volume
        source: "mydata"
        target: "/var/lib/postgresql/data"
    container_name: leafy-postgres
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 256M
    restart: always

~/leafy/leafy-postgresql/Dockerfile

#PostgreSQL 13 버전을 베이스 이미지로 사용
FROM postgres:13

#init.sql파일을 /docker-entrypoint-initdb.d/ 로 복사, /docker-entrypoint-initdb.d/에 있는 sql문은 컨테이너가 처음 실행 시 자동실행됨
COPY ./init/init.sql /docker-entrypoint-initdb.d/

#postgresql.conf파일을 /etc/postgresql/postgresql.conf 로 복사, 기본 설정 파일을 덮어쓰기하여 새로운 설정 적용
COPY ./config/postgresql.conf /etc/postgresql/custom.conf

#계정정보 설정
ENV POSTGRES_USER=myuser
ENV POSTGRES_PASSWORD=mypassword
ENV POSTGRES_DB=mydb

EXPOSE 5432

CMD ["postgres", "-c", "config_file=/etc/postgresql/custom.conf"]

2. backend
composes/backend.yaml

services:
  leafy-backend:
    build: ../leafy-backend
    image: leafy-backend:5.0.0-compose
    environment:
      - DB_URL=leafy-postgres
    depends_on:
      - "leafy-postgres"
    container_name: leafy-backend
    deploy:
      resources:
        limits:
          cpus: '1.5'
          memory: 512M
    restart: on-failure

~/leafy/leafy-backend/Dockerfile

# 빌드 이미지로 OpenJDK 11 & Gradle을 지정
FROM gradle:7.6.1-jdk11 AS build

# 소스코드를 복사할 작업 디렉토리를 생성
WORKDIR /app

# 라이브러리 설치에 필요한 파일만 복사
COPY build.gradle settings.gradle ./

RUN gradle dependencies --no-daemon

# 호스트 머신의 소스코드를 작업 디렉토리로 복사
COPY . /app

# Gradle 빌드를 실행하여 JAR 파일 생성
RUN gradle clean build --no-daemon
RUN cp "build/libs/$(ls -lh build/libs/ | grep "SNAPSHOT.jar$" | awk '{print $9}')" leafy.jar

# 런타임 이미지로 OpenJDK 11-jre-slim 지정
FROM openjdk:11-jre-slim

# 애플리케이션을 실행할 작업 디렉토리를 생성
WORKDIR /app

# 빌드 이미지에서 생성된 JAR 파일을 런타임 이미지로 복사
COPY --from=build /app/build/libs/*.jar /app/leafy.jar

EXPOSE 8080 
ENTRYPOINT ["java"] 
CMD ["-jar", "leafy.jar"]

3. frontend
composes/frontend.yaml

services:
  leafy-front:
    build: ../leafy-frontend
    image: leafy-front:5.0.0-compose
    environment:
      - BACKEND_HOST=leafy-backend
    ports:
      - 80:80
    depends_on:
      - "leafy-backend"
    container_name: leafy-frontend
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 64M
    restart: on-failure

~/leafy/leafy-frontend/Dockerfile

# 빌드 이미지로 node:14 지정 
FROM node:14 AS build

WORKDIR /app

# 라이브러리 설치에 필요한 파일만 복사
COPY package*.json .

# 라이브러리 설치
RUN npm ci

# 소스코드 복사
COPY . /app

# 소스코드 빌드
RUN npm run build

# 프로덕션 스테이지
FROM nginx:1.21.4-alpine 
COPY nginx.conf /etc/nginx/conf.d/default.conf.template
ENV BACKEND_HOST leafy
ENV BACKEND_PORT 8080

COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh

# 빌드 이미지에서 생성된 dist 폴더를 nginx 이미지로 복사
COPY --from=build /app/dist /usr/share/nginx/html

EXPOSE 80
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

‣ 실행

다음 명령어를 실행하여 컨테이너를 생성
~/leafy

docker-compose up -d --build

http://<IP>로 접속
image


‣ 트러블슈팅

패스워드가 맞지 않음.

이메일이 틀린건가 해서 테이블을 뒤져보기로 함.

그전에 postgresql 컨테이너의 경우 내가 직접 구축한 것이 아닌 다른 사람의 이미지를 사용한거여서

어떤 db와 user,password를 사용 중인지 알 방법이 없음.

아래 명령어로 해당 컨테이너에 어떤 환경 변수가 들어가있는지 확인해보기로 함.

docker image inspect leafy-postgres:5.0.0-compose | grep -A10 "Env"

image


알아낸 DB와 User, Password로 DB에 접속하여 users 테이블에 내가 적은 이메일이 실제로 존재하는지 확인.

docker exec -it leafy-postgres /bin/bash
# DB 접속
root@1fdf13c755ef:/# psql -U myuser -d mydb

image


Loading script...